<?php


namespace App\Service\Baiyou;


use App\Model\Baiyou\Clinic;
use App\Model\Baiyou\PatientInfusionQueue;
use App\Model\Baiyou\PatientUser;
use App\Utils\BaiduTts;
use App\Utils\Common;
use App\Utils\DateHelp;
use App\Utils\TaskHelp;
use App\Utils\WebSocketMessage;
use EasySwoole\EasySwoole\Config;

class PatientInfusionQueueService
{

    /**
     * 大屏等待队列列表
     * @param int|null $type
     * @return array
     */
    public function getScreenWaitQueueList(int $projectId, ?int $type = null): array
    {
        $data = $this->getWaitingList($projectId, $type);

        return $this->getQueueListFormat($data);
    }

    /**
     * 格式化
     * @param array $data
     * @param array $drugList
     * @return array
     */
    public function getQueueListFormat(array $data): array
    {
        $jdList = $jzList = [];
        foreach ($data as $row) {
            $item = [
                'id' => $row['id'],
                'type' => $row['type'],
                'order_num' => $row['order_num'],
                'patient' => [
                    'id' => $row['patient_user_id'],
                    'name' => $this->getHideName($row['name']),
                    'age' => $row['age'],
                    'gender' => PatientUser::$genders[$row['gender']] ?? '',
                    'clinic_name' => $row['clinic_name'],
                ],
            ];

            if ($row['type'] == PatientInfusionQueue::TYPE_JD) {
                $jdList[] = $item;
            } else {
                $jzList[] = $item;
            }
        }

        return [
            'jd' => $jdList,
            'jz' => $jzList,
        ];
    }



    /**
     * 队列信息
     * @param int $id
     * @return array
     */
    public function getQueueInfo(int $id): array
    {
        $query = $this->getQueueListQuery();
        $data = $query->where(['iq.id' => $id])->get();
        if (empty($data)) {
            return [];
        }

        $baiduTts = new BaiduTts();
        $mp3File = $baiduTts->getAudioFile($this->getAudioText($data['name'], $data['clinic_name'], $data['type']));

        $urlConfig = Config::getInstance()->getConf("URL");

        $res = $this->getQueueListFormat([$data]);
        $return = $data['type'] == PatientInfusionQueue::TYPE_JD ? $res['jd'][0] : $res['jz'][0];
        $return['audio_file'] = $urlConfig['ws'].'/'.$mp3File;
        return $return;
    }

    /**
     * 获取叫号模板内容
     * @param string $name
     * @return string
     */
    private function getAudioText(string $name, string $clinicName, int $type): string
    {
        $typeStr = PatientInfusionQueue::$callTypes[$type] ?? '';
        $action = $type == PatientInfusionQueue::TYPE_JD ? '输液' : '注射';
        return "请{$clinicName}{$name}到{$typeStr}进行{$action}";
    }

    /**
     * 获取屏蔽姓名
     * @param string $name
     * @return string
     */
    public function getHideName(string $name): string
    {
        $strlen = mb_strlen($name);
        $firstStr = mb_substr($name, 0, 1);
        if ($strlen <= 2) {
            return $firstStr.'*';
        }

        $lastStr = mb_substr($name, -1, 1);
        return "{$firstStr}*{$lastStr}";
    }

    /**
     * 通知白友排队成功
     * @param int $projectId
     * @param string $msgType
     */
    /*public function sendByNoticeList(int $projectId, string $msgType)
    {
        // 通知白友排队成功
        TaskHelp::asyncSend2ByTask($projectId, $msgType, []);
    }*/

    /**
     * 通知大屏排队成功
     * @param int $projectId
     * @param int $id
     */
    public function sendScreenCall(int $projectId, int $id)
    {
        // 通知大屏叫号成功
        $data = $this->getQueueInfo($id);
        TaskHelp::asyncSend2CallScreenTask($projectId, WebSocketMessage::QueueCallScreenRes, $data);
    }

    /**
     * 通知大屏排队成功
     * @param int $projectId
     */
    public function sendScreenNoticeList(int $projectId)
    {
        $data = $this->getScreenWaitQueueList($projectId);
        TaskHelp::asyncSend2CallScreenTask($projectId, WebSocketMessage::QueueListScreenRes, $data);
    }

    /**
     * 通知大屏输液完成
     * @param int $projectId
     */
    public function sendScreenInfusionNoticeList(int $projectId, int $id, int $type)
    {
        $data = [
            'id' => $id,
            'type' => $type,// 【1静滴、2肌注】
        ];
        TaskHelp::asyncSend2CallScreenTask($projectId, WebSocketMessage::QueueInfusionScreenRes, $data);
    }

    /**
     * 通知白友刷新排队
     * @param int $projectId
     */
    public function sendByQueueNoticeList(int $projectId)
    {
        TaskHelp::asyncSend2ByTask($projectId,WebSocketMessage::QueueListByRes, null);
    }

    /**
     * 通知白友刷新患者
     * @param int $projectId
     */
    public function sendByPatientNoticeList(int $projectId)
    {
        TaskHelp::asyncSend2ByTask($projectId,WebSocketMessage::PatientListByRes, null);
    }

    /**
     * 队列sql
     * @return PatientInfusionQueue|\EasySwoole\ORM\AbstractModel
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     */
    private function getQueueListQuery()
    {
        $query = PatientInfusionQueue::create()->alias('iq')
            ->field([
                'iq.id', 'iq.type', 'iq.patient_user_id', 'iq.order_num',
                'u.name', 'u.age', 'u.gender',
                'c.name clinic_name',
            ])
            ->join(PatientUser::create()->getTableName().' u', 'u.id = iq.patient_user_id')
            ->join(Clinic::create()->getTableName().' c', 'c.id = u.clinic_id', 'LEFT');

        return $query;
    }

    /**
     * 等待+进行中队列
     * @param int $projectId
     * @param int|null $type
     * @return array
     */
    private function getWaitingList(int $projectId, ?int $type = null): array
    {
        $today = DateHelp::today();

        $query = $this->getQueueListQuery();

        $query->where([
                'iq.project_id' => $projectId,
                'iq.status' => PatientInfusionQueue::STATUS_WAIT,
            ])
            ->where('iq.created_at', $today['start'], '>=')
            ->where('iq.created_at', $today['end'], '<=');

        if (is_numeric($type) && in_array($type, [PatientInfusionQueue::TYPE_JD, PatientInfusionQueue::TYPE_JZ])) {
            $query->where(['iq.type' => $type]);
        }

        $data = $query->order('iq.order_num', 'ASC')->all();

        return $data;
    }
}
